#主要负责界面上控件的事件处理
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QSize,Qt
from UI.uiMainWindow import Ui_MainWindow
from PyQt5.QtWidgets import QDesktopWidget,QMessageBox,QMainWindow,QFileDialog
from PyQt5.QtGui import QIcon, QPixmap,QImage
import sys
import os
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import pyqtSignal
from detectThread import DetectThread
from train import MODEL_DIR_NAME
import cv2
import numpy as np
from PIL import Image as im

DEFAULT_TEST_PIC_PATH='./JPEGImages/test'

class MainWindow(QMainWindow,Ui_MainWindow):
    img_path_sign = pyqtSignal(str)
    model_path_sign=pyqtSignal(str)
    res_sign = pyqtSignal(str)
    load_sign = pyqtSignal(str)
    detect_sign=pyqtSignal(str)
    turn_page_sign=pyqtSignal(int)
    show_crop_sign=pyqtSignal(int)
    def __init__(self,parent=None):
        super(MainWindow, self).__init__(parent)

        icon = QIcon()
        icon.addPixmap(QPixmap(os.getcwd() + '/cattle.ico'))
        self.setWindowIcon(icon)
        self.center()
        # ui = Ui_MainWindow()
        self.setupUi(self)
        self.choosen_pic = ''
        self.img_path_sign.connect(self.showImgPathText)
        self.bt_load_pic.clicked.connect(self.openimg)
        self.bt_load_model.clicked.connect(self.openmodel)

        self.detect_th = DetectThread()
        self.load_sign.connect(self.detect_th.my_loadmodel)

        self.model_path_sign.connect(self.showModelPathText)
        self.bt_detect.clicked.connect(self.detectCattle)
        self.detect_sign.connect(self.detect_th.main_detect)

        self.group_num=0
        self.detect_th.detect_finish_sign.connect(self.showDetectRes)
        self.turn_page_sign.connect(self.turnPage)
        self.bt_page_down.clicked.connect(self.pageDown)
        self.bt_page_up.clicked.connect(self.pageUp)
        self.show_crop_sign.connect(self.showCrop)

        self.check_save_txt.stateChanged.connect(self.saveTxtChoose)
        self.statusBar().showMessage('界面初始化完成')
        self.statusbar.setFixedHeight(40)

    def center(self):
        #获取屏幕的大小
        screen=QDesktopWidget().screenGeometry()
        #获取窗口的大小
        size=self.geometry()
        #将窗口移动到屏幕中央
        self.move((screen.width() - size.width()) /2,(screen.height() - size.height()) /2)

    def openimg(self):
        imgName, imgType = QFileDialog.getOpenFileName(self,caption='选择文件',directory=DEFAULT_TEST_PIC_PATH,filter= "*.jpeg;;*.jpg;;*.png;;*.webp;;All Files(*)")

        if imgName!='':
            if imgType not in ['*.jpg','*.png','*.jpeg','*.webp']:
                self.criticalMessage('非合法图片，请重新选择')
                self.openimg()
                return
            #reshape the pic to fit the label text and keep the aspect ratio
            img=QPixmap(imgName).scaled(QSize(self.srcQlabel.width(),self.srcQlabel.height()),Qt.KeepAspectRatio)
            self.srcQlabel.setPixmap(img)
            self.img_path_sign.emit(imgName)
            self.detect_th.detected_flag = False
        self.statusBar().showMessage('成功载入图片')

    def showImgPathText(self,path_str):
        self.img_path_text.setText(path_str)  # 将读取到的内容放到textEdit小部件中
        self.choosen_pic=path_str

    def showResText(self,res_str):
        self.resTextEdit.setText(res_str)

    def criticalMessage(self,message_str):
        reply = QMessageBox.critical(self,'警告',message_str,QMessageBox.Yes,QMessageBox.Yes)
        self.statusBar().showMessage('警告!')

    def openmodel(self):
        modelName, modelType = QFileDialog.getOpenFileName(self, caption='选择文件', directory=os.path.join(os.getcwd(),MODEL_DIR_NAME),
                                                       filter="*pt;;All Files(*)")
        if modelName!='':
            if modelType != '*pt':
                self.criticalMessage('非合法模型，请重新选择')
                self.openmodel()
                return
            if self.detect_th.weights==modelName:
                return
        self.statusBar().showMessage('开始载入模型...')
        self.load_sign.emit(modelName)
        self.model_path_sign.emit(modelName)
        # 启动线程
        self.detect_th.start()
        self.detect_th.detected_flag = False
        self.statusBar().showMessage('成功载入模型')

    def showModelPathText(self,model_path):
        self.model_path_text.setText(model_path)
        self.detect_th.weights=model_path


    def detectCattle(self):
        if(not os.path.exists(self.choosen_pic)):
            self.openimg()
            if (not os.path.exists(self.choosen_pic)):
                return
        if(not os.path.exists(self.detect_th.weights)):
            self.openmodel()
            if (not os.path.exists(self.detect_th.weights)):
                return

        self.statusBar().showMessage('开始检测...')
        self.detect_sign.emit(self.choosen_pic)

    def showDetectRes(self,found):
        # if self.detect_th.detected_flag == False:
        #     self.criticalMessage('重载模型/图像后还未重新检测')
        # print(found)
        self.statusBar().showMessage('检测完成:'+'找到目标' if found else '未找到目标')
        if(found):
            pixmap = QPixmap(self.detect_th.res_im0).scaled(QSize(self.srcQlabel.width(),self.srcQlabel.height()),Qt.KeepAspectRatio)
            self.srcQlabel.setPixmap(pixmap)
            self.group_num = 0
            self.pageDown()
        else:
            self.resQlabel.setPixmap(QPixmap(""))
            self.resTextEdit.setText("未找到目标")

    def pageDown(self):
        self.turn_page_sign.emit(1)

    def pageUp(self):
        self.turn_page_sign.emit(-1)

    #num:将按钮的点击信号与组件的翻页方法 turn_page() 绑定， 传入 1 为下一页， -1 为上一页。
    def turnPage(self, num):  # 图像列表翻页
        flag = len(self.detect_th.crops)
        if self.group_num == 1 and num == -1:  # 到首页时停止上翻
            QMessageBox.about(self, "Remind", "This is the first page!")
        elif (self.group_num == flag and num == 1) or flag == 0:  # 到末页页时停止下翻
            QMessageBox.about(self, "Remind", "No more image! ")
        else:
            self.group_num += num  # 翻页

        # self.group_num = (self.group_num+num)%flag+1

        if flag!=0:
            self.show_crop_sign.emit(self.group_num)

    def showCrop(self,num):
        self.resQlabel.setPixmap(self.detect_th.crops[num-1].scaled(QSize(self.resQlabel.width(),self.resQlabel.height()),Qt.KeepAspectRatio))
        self.resTextEdit.setText(self.detect_th.labels[num-1])

    def saveTxtChoose(self):
        self.detect_th.save_txt = True if self.check_save_txt.isChecked() else False


